package io.kiki.sba.registry.common.model.store;


import io.kiki.sba.registry.common.model.DataCenterPushInfo;
import io.kiki.sba.registry.exception.SofaRegistryRuntimeException;
import io.kiki.sba.registry.util.StringFormatter;
import lombok.Getter;
import lombok.Setter;
import org.springframework.util.StringUtils;

import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;

@Setter
@Getter
public class PushData<T> {
    private final T payload;

    private final Map<String, String> segment2DataCenter;

    private final Map<String, DataCenterPushInfo> dataCenterPushInfo;

    public PushData(T payload, Map<String, DataCenterPushInfo> dataCenterPushInfo) {
        this.payload = payload;

        if (dataCenterPushInfo == null) {
            this.dataCenterPushInfo = Collections.EMPTY_MAP;
            this.segment2DataCenter = Collections.EMPTY_MAP;
            return;
        }
        this.dataCenterPushInfo = dataCenterPushInfo;

        Map<String, String> segment2DataCenter = new HashMap<>();
        for (Entry<String, DataCenterPushInfo> entry : dataCenterPushInfo.entrySet()) {
            for (String segment : entry.getValue().getSegments()) {
                segment2DataCenter.put(segment, entry.getKey());
            }
        }
        this.segment2DataCenter = segment2DataCenter;
    }


    public void addSegmentInfo(String segment, String encoding, int encodeSize) {
        String dataCenter = segment2DataCenter.get(segment);
        if (StringUtils.isEmpty(dataCenter)) {
            throw new SofaRegistryRuntimeException(StringFormatter.format("[addSegmentInfo]not find dataCenter for segment: %s", segment));
        }
        DataCenterPushInfo dataCenterPushInfo = this.dataCenterPushInfo.get(dataCenter);
        if (dataCenterPushInfo == null) {
            throw new SofaRegistryRuntimeException(StringFormatter.format("[addSegmentInfo]not find dataCenterPushInfo for dataCenter:%s, segment: %s", dataCenter, segment));
        }
        dataCenterPushInfo.addSegmentInfo(segment, encoding, encodeSize);
    }
}
